import { Injectable } from '@angular/core';
import { Action, Selector, State, StateContext } from '@ngxs/store';
import { tap } from 'rxjs/operators';
import { defaultEntityState, EntityStateModel, EntityStore } from '../../core';
import { IdentityUserDto, IdentityUserService } from '../proxy/identity';

export class SetDefaultRoleNames {
  static readonly type = '[UserDetailViewModel] Set Default RoleNames';
  constructor(public payload: string[]) {}
}

export class SetCurrentUserRoleNames {
  static readonly type = '[UserDetailViewModel] Set CurrentUser RoleNames';
  constructor(public payload: string) {}
}

export interface IdentityUserDetail extends EntityStateModel<IdentityUserDto> {
  selectedRoleNames: string[];
}

@State<IdentityUserDetail>({
  name: 'IdentityUserDetail',
  defaults: { ...defaultEntityState(), selectedRoleNames: [] },
})
@Injectable()
export class IdentityUserDetailState extends EntityStore<IdentityUserDto> {
  protected onGet(payload: any): Promise<IdentityUserDto> {
    return this.identityUserService.get(payload).toPromise();
  }
  protected onSave(payload: any): Promise<IdentityUserDto> {
    return this.identityUserService.create(payload).toPromise();
  }
  protected onUpdate(payload: any): Promise<IdentityUserDto> {
    return this.identityUserService.update(payload['id'], payload).toPromise();
  }
  protected onDelete(payload: any): Promise<any> {
    return this.identityUserService.delete(payload).toPromise();
  }

  @Selector()
  static getRoleNames({ selectedRoleNames }: IdentityUserDetail): string[] {
    return selectedRoleNames;
  }

  constructor(protected identityUserService?: IdentityUserService) {
    super(IdentityUserDetailState);
  }

  @Action(SetDefaultRoleNames)
  setRoleNames({ patchState }: StateContext<IdentityUserDetail>, { payload }: SetDefaultRoleNames) {
    patchState({
      selectedRoleNames: payload,
    });
  }

  @Action(SetCurrentUserRoleNames)
  setCurrentUserRoleNames(
    { patchState }: StateContext<IdentityUserDetail>,
    { payload }: SetCurrentUserRoleNames
  ) {
    return this.identityUserService.getRoles(payload).pipe(
      tap(result => {
        patchState({
          selectedRoleNames: result.items.map(x => x.name),
        });
      })
    );
  }
}
